﻿using K9Nano.Updater.Server.Authorization;
using K9Nano.Updater.Server.Internals;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;

namespace K9Nano.Updater.Server;

public static class StartupExtensions
{
    public static IK9UpdateServerBuilder AddK9UpdateServer(this IServiceCollection services, Action<K9UpdateOptions> configure)
    {
        services.Configure(configure);

        services.AddHttpContextAccessor();

        services.AddSingleton<IAuthorizationHandler, K9HashAuthorizationHandler>()
            .AddScoped<IClientContextAccessor, ClientContextAccessor>()
            .AddScoped<IReleaseStore, PhysicalReleaseStore>()
            .AddScoped<IReleaseManager, ReleaseManager>()
            ;

        var builder = new K9UpdateServerBuilder(services);
        return builder;
    }

    public static IK9UpdateServerBuilder UseClients(this IK9UpdateServerBuilder app, Action<Dictionary<string, string>> configure)
    {
        var clients = new Dictionary<string, string>();
        configure(clients);
        app.Services.AddSingleton<IClientStore>(new PlainClientStore(clients));
        return app;
    }


    public static IEndpointRouteBuilder UseK9Update(this IEndpointRouteBuilder app)
    {
        var options = app.ServiceProvider.GetRequiredService<IOptions<K9UpdateOptions>>().Value;

        var group = app.MapGroup(options.RequestPath + "releases");

        group.MapGet("/latest", async ([FromServices] IReleaseManager manager,
            HttpContext context,
            [FromServices] IAuthorizationHandler filter) =>
        {
            if (!await filter.AuthorizeAsync(context))
            {
                return Results.StatusCode(403);
            }
            var result = await manager.GetLatestVersionAsync(context.RequestAborted);
            return Results.Json(result);
        }).WithSummary("获取最新版本");

        group.MapGet("/tags/v{version}", async (Version version,
            [FromServices] IReleaseManager manager,
            HttpContext context,
            [FromServices] IAuthorizationHandler filter) =>
        {
            if (!await filter.AuthorizeAsync(context))
            {
                return Results.StatusCode(403);
            }
            var result = await manager.GetMetadataAsync(version, context.RequestAborted);
            return Results.Json(result);
        }).WithSummary("获取版本元数据");

        group.MapGet("/files/v{version}/{*fileUri}", async (Version version,
            string fileUri,
             [FromServices] IReleaseManager manager,
            HttpContext context,
            [FromServices] IAuthorizationHandler filter) =>
        {
            if (!await filter.AuthorizeAsync(context))
            {
                return Results.StatusCode(403);
            }
            var result = await manager.GetReleaseFileAsync(version, fileUri, context.RequestAborted);
            if (result == null)
            {
                return Results.NotFound();
            }
            return Results.Stream(result.FileStream, "application/octet-stream", result.FileName);
        }).WithSummary("下载文件");

        return app;
    }
}
